//定义LinkedList类
//（1）定义一个辅助类Node
/*
[1]定义类的语法
类名的首字母一定要大写
class 类名{
    //通过构造方法来初始化数据
    consturctor(){
        //进行数据的初始化
    }
    //普通方法
    //function1(){}
    //function2(){}
    //function3(){}
}
[2]使用类
//对象名称和类名不能一眼
const 对象名称=new 类名();
*/

//（1）定义一个辅助类Node
class Node {
    constructor(data) {
        //保存元素用
        this.element = data;
        //指向下个节点
        this.next = undefined;
    }
}
//定义LinkedList类
class LinkedList {
    constructor() {
            this.head = undefined;
            this.length = 0;
        }
        //实现具体的方法
        //1.从尾部进行插入
    push(data) {
        //1.从外部插入元素
        const node = new Node(data);
        let current;
        //分情况讨论
        //（1.1）插入值为第一个元素
        if (this.head == null) {
            this.head = node;
        } else {
            //链表从头开始查询，没有索引
            current = this.head;
            //对于无法确定循环次数的循环，使用while
            while (current.next != null) {
                current = current.next;
            }
            //等找到最后的位置，将新的node插入到该位置之后
            current.next = node;
        }
        this.length++;
    }

    //insert()指定位置进行插入
    insert(position, data) {
        if (position < 0 || position > this.length) {
            return false;
        }
        //insert()方法实现：
        // 1、调用辅助类node，创建一个节点
        //2、插入节点（分情况讨论）
        // 2.1头部
        // 2.2其他位置
        //节点
        //对象实例化时类的括号里面传递元素取决于构造方法
        const node = new Node(data);
        if (position === 0) {
            //拿到之前的头节点
            const current = this.head;
            //新创建的节点指向原来的头节点
            node.next = current;
            //head指向新的头节点
            this.head = node;
        } else {
            //定义两个新的节点：previous,current
            let previous = null;
            let current = this.head;
            let index = 0;
            //找待插入的位置
            while (index++ < position) {
                //节点后移
                previous = current;
                current = current.next;
            }
            //找到正确位置，进行插入
            previous.next = node;
            node.next = current;
        }
        this.length++;
        return true;

    }
    removeAt(position) {
        //1.检查传入参数的有效性 position[0,length-1]才是有效的
        if (position >= 0 && position < this.length) {
            //进行处理
            //注意赋值等号=和逻辑等号==、===的区别
            //1.poisiton===0
            let current = this.head;
            if (position === 0) {
                this.head = current.next;
                this.length--;
                return current.element;
            }
            //2.移除其他元素的元素
            else {
                let previous = null;
                let current = this.head;
                let index = 0;
                //找待插入的位置
                while (index++ < position) {
                    previous = current;
                    current = previous.next;
                }
                previous.next = current.next;
            }
            this.length--;
            return current.element;
        }
        return undefined;
    }
    getElementAt(position) {
            if (position >= 0 && position <= this.length) {
                let index = 0;
                let current = this.head;
                while (index++ < position) {
                    current = current.next;
                }
                return current;
            }
            return undefined;
        }
        //indexOf(element)返回，功能，传入一个元素，返回该元素的位置
    indexOf(data) {
        let current = this.head;
        let index = 0;
        while (current) {
            if (current.element === data) {
                return index;
            }
            index++;
            current = current.next;
        }
        return -1;
    }
    remove(data) {
        let index = this.indexOf(data);
        if (index === -1) {
            return;
        }
        this.removeAt(index);
    }
    toString() {
        if (this.head == null) {
            return '';
        }
        let str = this.head.element;
        let current = this.head.next;
        while (current != null) {
            //隐式转换
            //数值+" "
            str = str + ',' + current.element;
            current = current.next;
        }
        return str;
    }
    printList() {
        console.log(this.toString());
    }
}

//实现链表的插入

//进行测试
const linkedlist = new LinkedList();
linkedlist.push('a');
linkedlist.push('b');
linkedlist.push('c');
// console.log(linkedlist.removeAt(0));
// console.log(linkedlist.getElementAt(1));
// console.log(linkedlist.indexOf('b'));
console.log(linkedlist.toString());